package librus.model
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.filesystem.File;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.utils.getTimer;
	
	import mx.controls.Image;
	import mx.core.mx_internal;
	import mx.graphics.codec.JPEGEncoder;
	import mx.graphics.codec.PNGEncoder;
	
	import org.alivepdf.images.gif.encoder.GIFEncoder;

	public class Card extends EventDispatcher
	{
		public static const SIZE_WIDTH_MM:Number = 62;
		public static const SIZE_HEIGHT_MM:Number = 86.3;
		
		public static const LOADED:String = "loaded";
		public static const PREPARED:String = "prepared";
		
		private var __data:BitmapData;
		private var __byteArray:ByteArray;
		
		private var __loader:Loader;
		private var __file:File;
		
		[Bindable] public var count:int;
		[Bindable] public var name:String;
		
		public function Card(file:File)
		{
			count = 1;
			
			__file = file;
			var name:String =  file.name.split(".")[0];
			if (name.length > 50)
				name = name.substr(0,50) + "...";
			this.name = name;
		}
		
		public function prepareForPrint():void
		{
			if (data)
			{
				prepare();
			}
			else
			{
				addEventListener(LOADED, onLoaded);
				load();
			}
		}
		
		protected function onLoaded(event:Event):void
		{
			removeEventListener(LOADED, onLoaded);
			prepare();
		}
		
		private function prepare():void
		{
			var tmp:BitmapData = __data;
			
			var data:BitmapData = trimColor();
			__data= data;
			data = trimColor(0xffffff);
					
			tmp = __data;
			
			if ( __data.width > __data.height)
				data = rotateLeft(data);
					
			encode(data);
			dispatchEvent(new Event(PREPARED));
		}
		
		public function get data():BitmapData
		{
			return __data;
		}

		public function get byteArray():ByteArray
		{
			return __byteArray;
		}
		
		public function load():void
		{
			__loader = new Loader;
			__loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
			__loader.load(new URLRequest(__file.nativePath));
		}
		
		protected function onComplete(event:Event):void
		{
			__loader.removeEventListener(Event.COMPLETE, onComplete);
			
			__data = (__loader.contentLoaderInfo.content as Bitmap).bitmapData;
			
			dispatchEvent(new Event(LOADED));
			__loader = null;
		}
		
		private function rotateLeft(data:BitmapData):BitmapData
		{
			var matrix:Matrix = new Matrix();
				matrix.rotate(-1*Math.PI/2);
				matrix.ty = data.width;
				
			var bd:BitmapData = new BitmapData(data.height, data.width);
				bd.draw(data,matrix);
				
			return bd;
		}
		
		public function trimColor(color:uint=0):BitmapData
		{
			var left:int = getBorder(leftBorder, color);
			var right:int =getBorder(rightBorder, color);
			var top:int = getBorder(topBorder, color);
			var bot:int =getBorder(botBorder, color);
					
			var rect:Rectangle = new Rectangle(left,top,__data.width-left-right,__data.height-top-bot);
			var data:BitmapData = new BitmapData(rect.width,rect.height,false);
			
			data.copyPixels(__data,rect,new Point);
			return data;
		}
		
		private function getBorder(func:Function, color:uint):int
		{
			var result:int =0;
			
			while(func(result,color))
				result++;
			
			return result;
		}
		
		protected function leftBorder(index:int, color:uint):Boolean
		{
			var pixel:uint = __data.getPixel(index,__data.height/2);
			return pixel == color;
		}
		
		protected function rightBorder(index:int, color:uint):Boolean
		{
			var pixel:uint = __data.getPixel(__data.width-index-1,__data.height/2);
			return pixel == color;
		}
		
		protected function topBorder(index:int, color:uint):Boolean
		{
			var pixel:uint = __data.getPixel(__data.width/2, index) ;
			return pixel == color;
		}
		
		protected function botBorder(index:int, color:uint):Boolean
		{
			var pixel:uint = __data.getPixel(__data.width/2, __data.height-index-1);
			return pixel == color;
		}
		
		private function encode(data:BitmapData):void
		{
			var start:int = getTimer();
			var encoder:JPEGEncoder = new JPEGEncoder;
			__byteArray = encoder.encode(data);
			
			trace("Encoded in:",(getTimer() - start)/1000,"seconds");
		}
	}
}